home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / doc / multiple-values < prev    next >
Lisp/Scheme  |  1989-08-28  |  3KB  |  95 lines

  1.  
  2. Proclaimed functions of a fixed number of args are much more
  3. efficient.   It is still possible to pass multiple values
  4. efficiently (but not quite with the CL semantics)
  5.  
  6. Here are two examples, one using ordinary multiple-value-setq
  7. and the other our-multiple-value-setq.
  8. For 1,000,000 calls:
  9.  
  10. Type   :      CL 2 values   our 2 values              1 value
  11. Time   :         7.9 sec      3.5                     2.35
  12. name   :         foo-mv       foo-our-mv              foo 
  13. Uses   : multiple-value-setq our-multiple-value-setq  Only 1 value passed.
  14.  
  15. (defun foo-mv (n)
  16.   (let (x y)
  17.   (sloop for i below n
  18.      do (multiple-value-setq(x y) (goo-mv)))))
  19.  
  20. (defun goo-mv () (values 1 2))
  21.  
  22.  
  23. And then an equivalent one:
  24. (proclaim '(function foo-our-mv (t) t))
  25. (proclaim '(function goo-our-mv () t))
  26. (defun foo-our-mv (n)
  27.   (let (x y)
  28.    (sloop for i below n
  29.             do (our-multiple-value-setq (x y) (goo-our-mv)))
  30.   (list x y)))    
  31.  
  32. (defun goo-our-mv  () (our-values 1 2))
  33.  
  34. The times:
  35. >(time (foo-our-mv 1000000))
  36. real time : 3.617 secs
  37. run time  : 3.583 secs
  38. (1 2)
  39. >(time (foo-mv 1000000))
  40. real time : 8.033 secs
  41. run time  : 7.800 secs
  42. (1 2)
  43.  
  44. Here are the our-mv macros:
  45.  
  46. (use-package "SLOOP")
  47.  
  48.  
  49. (defmacro our-values (a &rest l)
  50.   (or (< (length l) (length *vals*)) (error "too many values"))
  51.   `(prog1 ,a ,@ (sloop for v in l
  52.                for u in *vals*
  53.                collect `(setq ,u ,v))))
  54.  
  55. (defmacro our-multiple-value-setq ((x &rest l) form)
  56.   (or (< (length l) (length *vals*)) (error "too many values"))
  57.   `(prog1 (setq ,x ,form)
  58.      ,@ (sloop for w in *vals*
  59.            for v in l
  60.            collect `(setq ,v ,w))))
  61.  
  62. (defvar *vals*
  63.   '(*val1* *val2* *val3* *val4* *val5* *val6* *val7* *val8* *val9* *val10*))
  64.  
  65.  
  66. (defvar *val1* nil)
  67. (defvar *val2* nil)
  68. (defvar *val3* nil)
  69. (defvar *val4* nil)
  70. (defvar *val5* nil)
  71. (defvar *val6* nil)
  72. (defvar *val7* nil)
  73. (defvar *val8* nil)
  74. (defvar *val9* nil)
  75. (defvar *val10* nil)
  76.  
  77. ;; Note that this method does not penalize ordinary calls at all.
  78. ;; It is not the same as the common lisp multiple values in general:
  79. ;;    1)  The information on how many values are being passed is not
  80. ;;        recorded [ unless of course that number is one of the values ! ]
  81. ;;    2)  If you ask for more values than were specified you will get
  82. ;;        a random value.   Common lisp values would say you get nil.
  83. ;; Now it is true that it would be possible to make AKCL pass multiple
  84. ;; values more efficiently, but this is really a large overhaul of the
  85. ;; system.   There are lots of system functions, hand coded using the
  86. ;; old scheme.   I have been thinking about ways to do this for the
  87. ;; last little while, but have not settled on anything.
  88.  
  89. Bill
  90.  
  91.  
  92.  
  93.  
  94.  
  95.